#ifndef __LOGGER_H
#define __LOGGER_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32h7xx_hal.h"
#include "stdio.h"
#include <string.h>

extern uint8_t block_flag;
extern uint8_t lprocess_flag;
extern uint8_t lcommand_flag;

//#define log_printf	usb_printf
#define log_printf	printf

#ifndef  USE_LOG
#define  USE_LOG						1
#endif


#ifndef  USE_LOG_DEBUG
#define  USE_LOG_DEBUG					1
#endif

#ifndef  USE_DUMP
#define  USE_DUMP						1
#endif

#ifndef  USE_BLOCK
#define  USE_BLOCK						1
#endif

#define ONLY_FILENAME(x) (strrchr(x, '\\') ? strrchr(x, '\\')+1 : x)

#if USE_BLOCK > 0
	#define BLOCK(s,...)				\
	do{									\
		if(lcommand_flag&2) {			\
			log_printf("\r\n[BLOCK %s:%d] ",	\
			ONLY_FILENAME(__FILE__),__LINE__);	\
			log_printf(s,##__VA_ARGS__);	\
			log_printf(",按任意键继续");	\
			block_flag = 0;				\
			while(block_flag==0);		\
			log_printf("\r\n");				\
		}else {							\
			INFO(s,##__VA_ARGS__);		\
		}								\
	} while(0)

#else
	#define BLOCK(x)
#endif

#if USE_LOG > 0
    #define LOG_CLS() \
            do{       \
                log_printf("\033[2J \033[3;1H\r\n");      \
             }while(0)
#if USE_LOG_DEBUG > 0
	#define LOG_DEBUG(s,...)	\
			do{	\
				if(lcommand_flag&1) {	\
					log_printf("\033[1;36m\r\n[DEBUG %s:%d] ",ONLY_FILENAME(__FILE__),__LINE__);	\
					log_printf(s,##__VA_ARGS__);	\
					log_printf("\33[0m\r\n");	\
				}	\
			}while(0)
#else
    #define LOG_DEBUG(s,...)
#endif
	#define LOG_INFO(s,...)	\
			do{			\
				if(lcommand_flag&1) {	\
				log_printf("\033[0;32m\r\n[INFO %s:%d] ",	\
					ONLY_FILENAME(__FILE__),__LINE__);			\
				log_printf(s,##__VA_ARGS__);	\
				log_printf("\33[0m\r\n");		\
				} \
			}while(0)

	#define LOG_ERROR(s,...)	\
			do{	\
				if(lcommand_flag&1) {	\
				log_printf("\033[0;31m\r\n[ERROR %s:%d] ",ONLY_FILENAME(__FILE__),__LINE__);	\
				log_printf(s,##__VA_ARGS__);	\
				log_printf("\33[0m\r\n");				\
				} \
			}while(0)

	#define LOG_ERROR2() 	\
			do{	\
				if(lcommand_flag&1) {	\
				log_printf("\033[0;31m\r\n[ERROR %s:%d] ",ONLY_FILENAME(__FILE__),__LINE__);	\
				log_printf("\33[0m\r\n");				\
				} \
			}while(0)

	#define LOG_ERROR3(cond) \
			do { \
				if(lcommand_flag&1) {	\
				if (!(cond)) { \
				  	log_printf("\033[0;31m\r\n[ERROR %s:%d] Failed to vertify the condition [\"%s\"]",ONLY_FILENAME(__FILE__),__LINE__,#cond); \
					log_printf("\33[0m\r\n");	\
				} \
				} \
			}while(0)

	#define LOG_ASSERT(cond)	\
			do { \
				if(lcommand_flag&1) {	\
					if (!(cond)) { \
						log_printf("\033[0;31m\r\n[ASSERT %s:%d] Failed to vertify thc condition [\"%s\"]",ONLY_FILENAME(__FILE__),__LINE__,#cond); \
						log_printf("\33[0m\r\n");	\
						while(1); \
					} \
				} \
			}while(0)
#else
    #define LOG_CLS()
	#define LOG_DEBUG(s,...)
	#define LOG_INFO(s,...)
	#define LOG_ERROR(s,...)
	#define LOG_ERROR2()
	#define LOG_ERROR3(cond)
	#define LOG_ERROR4(s,...)
	#define LOG_ASSERT(cond)
#endif


#if USE_DUMP > 0
#define LOG_DUMP(info, data, len,...) \
    do {                              \
        log_printf("\033[1;36m\r\n[DUMP] ");        \
        log_printf(info,##__VA_ARGS__);   \
	    log_printf("\r\n\r\n");               \
        log_dump(data, len);          \
        log_printf("\33[0m\r\n");                              \
    } while(0)


void log_test();

void log_dump(const uint8_t *data, uint16_t len);
void usb_printf(const char *format, ...);

#else
#define LOG_DUMP(info, data, len,...)
#endif

#ifdef __cplusplus
}
#endif

#endif
